package com.monkey.luffer.springboot.demo.basis.kcc;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.EndpointToRegion;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.AmazonS3EncryptionClientBuilder;
import com.amazonaws.services.s3.model.CryptoConfiguration;
import com.amazonaws.services.s3.model.CryptoMode;
import com.amazonaws.services.s3.model.EncryptionMaterials;
import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider;
import com.monkey.luffer.springboot.demo.basis.kcc.s3cmd.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

@Getter
@Setter
@AllArgsConstructor
public class MyS3Client {
	String accessKey;
	String secretKey;
	String endPoint;
	String encryptFlag;
	RsaConfig rsaConfig;

	@SneakyThrows
	public static void main(String[] args) {
		MyCmdlineHelper cmdlineHelper = new MyCmdlineHelper();
		MyCmd myCmd = cmdlineHelper.parse(args);

		MyS3Client myS3Client = new MyS3Client("properties.properties");
		AmazonS3 client = myS3Client.getClient();
		Map<String, S3Oper> cmds = new HashMap<>();
		cmds.put("list", new ListObjects());
		cmds.put("get", new GetObjects());
		cmds.put("put", new UploadObjects());
		cmds.put("gen", new GenerateOkFile());
		cmds.put("datascript", new AnalysisDatascript());
		cmds.put("compare", new CompareApollo());
		if (cmds.containsKey(myCmd.getCommand())){
			cmds.get(myCmd.getCommand()).request(client, myCmd);
		} else {
			System.out.println("args: --bucket --prefix --command list/get/put --dstPath --srcPath");
			System.out.println("上传： -c put -b ${bucket} -p ${prefix} -s ${src}");
			System.out.println("\t上传${src}路径下所有文件到${bucket}/${prefix}");
			System.out.println("下载： -c get -b ${bucket} -p ${prefix} -d ${dst}");
			System.out.println("\t下载${bucket}下所有前缀${prefix}的文件到本机${dst}目录");
			System.out.println("list： -c list -b ${bucket} -p ${prefix}");
			System.out.println("\t列出${bucket}下所有前缀${prefix}的文件");
			System.out.println("生成OK文件：-c gen -s ${src}");
			System.out.println("\t生成目录下的所有Ok文件");
			System.out.println("解析sql脚本：-c datascript -s ${src}");
			System.out.println("\t解析sql脚本");
			System.out.println("apollo版本对比，生成增量文件：-c compare  -s {project-root-path} -d {generate-file-path} -pre dev/v2.20_0810 -cur dev/v2.21_0824");
			System.out.println("\tapollo版本对比，生成增量文件");
		}
	}

	@SneakyThrows
	public MyS3Client(String fileName){
		try(InputStream in = MyS3Client.class.getClassLoader().getResourceAsStream(fileName)){
			Properties prop = new Properties();
			prop.load(in);
			RsaConfig rsaConfig = RsaConfig.builder()
					.privateKey(prop.getProperty("privateKey"))
					.publicKey(prop.getProperty("publicKey"))
					.build();
			this.setAccessKey(prop.getProperty("accessKey"));
			this.setSecretKey(prop.getProperty("secretKey"));
			this.setEndPoint(prop.getProperty("endPoint"));
			this.setEncryptFlag(prop.getProperty("encryptFlag"));
			this.setRsaConfig(rsaConfig);
			System.out.println("prop:" + prop);
		} catch (IOException ex) {
			ex.printStackTrace();
			throw ex;
		}
	}

	public final AmazonS3 getClient(){
		try {
			ClientConfiguration clientConfig = new ClientConfiguration();
			clientConfig.setProtocol(Protocol.HTTP);
			new BasicAWSCredentials(accessKey, secretKey);
			AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endPoint,
					EndpointToRegion.guessRegionNameForEndpoint(endPoint, "s3"));
			AmazonS3 s3Client = null;
			switch (encryptFlag) {
				case "LOOSE":
					s3Client = AmazonS3EncryptionClientBuilder.standard()
							.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
							.withClientConfiguration(new ClientConfiguration().withProtocol(Protocol.HTTP))
							.withEndpointConfiguration(endpointConfiguration)
							.withPathStyleAccessEnabled(true)
							.withCryptoConfiguration(new CryptoConfiguration(CryptoMode.AuthenticatedEncryption))
							.withEncryptionMaterials(new StaticEncryptionMaterialsProvider(new EncryptionMaterials(rsaConfig.getOrInitKeyPair())))
							.build();
					break;
				case "N":
					s3Client = AmazonS3ClientBuilder.standard()
							.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
							.withClientConfiguration(new ClientConfiguration().withProtocol(Protocol.HTTP))
							.withEndpointConfiguration(endpointConfiguration)
							.withPathStyleAccessEnabled(true)
							.build();
					break;
				default:
				s3Client = AmazonS3EncryptionClientBuilder.standard()
						.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
						.withClientConfiguration(new ClientConfiguration().withProtocol(Protocol.HTTP))
						.withEndpointConfiguration(endpointConfiguration)
						.withPathStyleAccessEnabled(true)
						.withCryptoConfiguration(new CryptoConfiguration(CryptoMode.StrictAuthenticatedEncryption))
						.withEncryptionMaterials(new StaticEncryptionMaterialsProvider(new EncryptionMaterials(rsaConfig.getOrInitKeyPair())))
						.build();
			}
			return s3Client;

		} catch (Throwable var5) {
			throw var5;
		}
	}

}
